#变量作用域：局部变量和全局变量
#局部变量：是定义在函数体内部的变量，即只在函数体内部生效。
def testA():
    a=100
    print(a)
testA()
# print(a)    报错：name'a' is not defined
#局部变量的作用：在函数体内部，临时保存数据，即当函数调用完成后，则销毁局部变量。

#全局变量：指的是在函数体内，外都能生效的变量。
#定义全局变量a
# a=100
# def testA():
#     print(a)     #访问全局变量a，并打印变量a存储的数据
# def testB():
#     a=200
#     print(a)       #访问全局变量a，并打印变量a存储的数据
#
# testA()       #100
# testB()       #200
# print(f'全局变量a={a}')      #全局变量a=100


a=100
def testA():
    print(a)     #访问全局变量a，并打印变量a存储的数据
def testB():
    #global关键字声明a是全局变量
    global a
    a=200
    print(a)       #访问全局变量a，并打印变量a存储的数据

testA()       #100
testB()       #200
print(f'全局变量a={a}')      #全局变量a=200

# 多函数程序执行流程
#1、定义全局变量
glo_num=0
def test1():
    global glo_num
    #修改全局变量
    glo_num=100

def test2():
    # 调用test1函数中修改后的全局变量
    print(glo_num)

#2.调用test1函数，执行函数内部代码：声明和修改全局变量
test1()
#3.调用test2函数，执行函数内部代码：打印
test2()    #100

#返回值作为参数传递
def test1():
    return 50
def test2(num):
    print(num)
#1.保存函数test1的返回值
result=test1()
#2.将函数返回值所在变量作为参数传递到test2函数
test2(result)      #50

#函数的返回值
def return_num():
    return 1
    return 2

result=return_num()
#只执行了第一个return，因为return可以退出当前函数，导致return下方的代码不执行
print(result)   #1

def return_num():
    return 1,2
result=return_num()
'''
1.return a,b写法，返回多个数据的时候，默认是元组类型
2.return后面可以连接列表、元组或字典，以返回多个值
'''
print(result)    #(1,2)

#函数的参数
#1、位置参数：调用函数时根据函数定义的参数位置来传递参数
def user_info(name,age,gender):
    print(f'您的名字是{name},年龄是{age},性别是{gender}')
#传递和定义参数的顺序及个数必须一致
user_info('TOM',20,'男')

#2、关键字参数：函数调用，通过“键=值”形式加以指定
user_info('Rose',age=20,gender='女')
user_info('小明',gender='男',age=16)

#3、缺省参数：默认参数，用于定义函数，为参数提供默认值
def user_info1(name,age,gender='男'):
    print(f'您的名字是{name},年龄是{age},性别是{gender}')
user_info1('TOM',20)
user_info1('Rose',18,'女')

#4、不定长参数：可变参数，用于不确定调用的时候会传递多少个参数
#包裹位置传递：
def user_info2(*args):
    print(args)
user_info2('TOM')
user_info2('TOM',18)
list1=[1,2,3]
user_info2(*list1)
#包裹关键字传递：
def user_info3(**kwargs):
    print(kwargs)
user_info3(name='TOM',age=18,id=110)
dict1={'name':'TOM','age':18,'id':110}    #提前定义字典
user_info3(**dict1)

#拆包：元组
def return_num():
    return 100,200
num1,num2=return_num()
print(num1)     #100
print(num2)     #200

#拆包：字典
dict1={'name':'TOM','age':18}
a,b=dict1
#对字典进行拆包，取出来的是字典的key
print(a)      #name
print(b)      #age
print(dict1[a])
print(dict1[b])

#交换变量值
# 需求：有变量a=10和b=20，交换两个变量的值
#方法一：借助第三变量存储数据
#定义中间变量
c=0
#将a=数据存储到c
c=a
#将b的数据20赋值到a，此时a=20
a=b
# 将之前c的数据10赋值到b，此时b=10
b=c
print(a)     #20
print(b)     #10

#方法二：
a,b=1,2
a,b=b,a
print(a)   #2
print(b)   #1

#引用：了解引用
#1.int类型
a=1
b=a
print(b)   #1
print(id(a))   #140723296396112
print(id(b))    #140723296396112

a=2
print(b)  #1,说明int类型为不可变类型
print(id(a))   #140723296396144
print(id(b))   #140723296396112

#列表
aa=[10,20]
bb=aa

print(id(aa))    #1772105982280
print(id(bb))    #1772105982280

aa.append(30)
print(bb)   #[10,20,30],列表为可变类型

print(id(aa))
print(id(bb))

#可变类型：列表，字典，集合
#不可变类型：字符串，数值（int，float），布尔型，元组